package com.graduation.check.controller;

import com.graduation.check.service.PaperInfoExtractionService;
import com.graduation.check.utils.ApiResponse;
import com.graduation.check.entity.User;
import com.graduation.check.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/student/paper")  // context-path=/api已在application.properties配置
public class PaperInfoExtractionController {

    @Autowired
    private PaperInfoExtractionService paperInfoExtractionService;

    @Autowired
    private UserMapper userMapper;

    @Value("${file.upload-dir:./uploads}")
    private String uploadDir;

    /**
     * 提交信息提取任务
     */
    @PostMapping("/extract-info")
    public ApiResponse<PaperInfoExtractionService.PaperExtractionResult> submitInfoExtraction(
            @RequestBody InfoExtractionRequest request,
            Authentication authentication) {
        try {
            Long studentId = getCurrentStudentId(authentication);
            log.info("学生 {} 提交信息提取任务，文件ID: {}, 原始文件名: {}", studentId, request.getFileId(), request.getFileName());

            String filePath = getFilePathById(request.getFileId());

            // 验证文件是否存在
            if (!Files.exists(Paths.get(filePath))) {
                return ApiResponse.error(404, "文件不存在");
            }

            PaperInfoExtractionService.ExtractionOptions options =
                    new PaperInfoExtractionService.ExtractionOptions();
            options.setExtractBasicInfo(request.getExtractOptions().isExtractBasicInfo());
            options.setExtractKeywords(request.getExtractOptions().isExtractKeywords());
            options.setExtractAbstract(request.getExtractOptions().isExtractAbstract());
            options.setExtractReferences(request.getExtractOptions().isExtractReferences());
            options.setLanguage(request.getExtractOptions().getLanguage());

            // 修改：传递原始文件名参数
            PaperInfoExtractionService.PaperExtractionResult result =
                    paperInfoExtractionService.extractPaperInfo(filePath, request.getFileName(), options, studentId);

            log.info("信息提取成功，学生ID: {}, 文件: {}", studentId, request.getFileName());
            return ApiResponse.success("信息提取完成", result);

        } catch (Exception e) {
            log.error("信息提取失败", e);
            return ApiResponse.error(500, "信息提取失败: " + e.getMessage());
        }
    }

    /**
     * 单独提取某项信息
     */
    @PostMapping("/extract-single")
    public ApiResponse<PaperInfoExtractionService.PaperExtractionResult> extractSingleItem(
            @RequestBody SingleExtractionRequest request,
            Authentication authentication) {
        try {
            Long studentId = getCurrentStudentId(authentication);
            log.info("学生 {} 单独提取 {} 信息，文件ID: {}, 原始文件名: {}", studentId, request.getItemType(), request.getFileId(), request.getFileName());

            String filePath = getFilePathById(request.getFileId());

            if (!Files.exists(Paths.get(filePath))) {
                return ApiResponse.error(404, "文件不存在");
            }

            PaperInfoExtractionService.ExtractionOptions options =
                    new PaperInfoExtractionService.ExtractionOptions();
            // 根据项目类型设置对应的提取选项
            switch (request.getItemType()) {
                case "basicInfo":
                    options.setExtractBasicInfo(true);
                    break;
                case "keywords":
                    options.setExtractKeywords(true);
                    break;
                case "abstract":
                    options.setExtractAbstract(true);
                    break;
                case "references":
                    options.setExtractReferences(true);
                    break;
            }

            // 修改：传递原始文件名参数
            PaperInfoExtractionService.PaperExtractionResult result =
                    paperInfoExtractionService.extractSingleItem(filePath, request.getFileName(), request.getItemType(), options, studentId);

            log.info("单独提取 {} 信息成功，学生ID: {}", request.getItemType(), studentId);
            return ApiResponse.success(request.getItemType() + "提取完成", result);

        } catch (Exception e) {
            log.error("单独提取 {} 信息失败", request.getItemType(), e);
            return ApiResponse.error(500, request.getItemType() + "提取失败: " + e.getMessage());
        }
    }

    /**
     * 上传论文文件
     */
    @PostMapping("/upload")
    public ApiResponse<FileUploadResponse> uploadPaper(
            @RequestParam("file") MultipartFile file,
            Authentication authentication) {
        try {
            Long studentId = getCurrentStudentId(authentication);

            if (file.isEmpty()) {
                return ApiResponse.badRequest("文件不能为空");
            }

            // 验证文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".pdf")) {
                return ApiResponse.badRequest("只支持PDF文件");
            }

            // 创建上传目录
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 生成唯一文件名
            String fileExtension = getFileExtension(originalFilename);
            String storedFileName = UUID.randomUUID().toString() + "." + fileExtension;
            Path filePath = uploadPath.resolve(storedFileName);

            // 保存文件
            Files.copy(file.getInputStream(), filePath);

            FileUploadResponse response = new FileUploadResponse();
            response.setFileId(storedFileName);
            response.setFileName(originalFilename); // 存储原始文件名
            response.setFilePath(filePath.toString());
            response.setFileSize(file.getSize());

            log.info("文件上传成功: {}, 原始文件名: {}, 学生ID: {}", storedFileName, originalFilename, studentId);
            return ApiResponse.success("文件上传成功", response);

        } catch (Exception e) {
            log.error("文件上传失败", e);
            return ApiResponse.error(500, "文件上传失败: " + e.getMessage());
        }
    }

    // 辅助方法 - 修复：使用真实的用户认证
    private Long getCurrentStudentId(Authentication authentication) {
        if (authentication != null && authentication.isAuthenticated()) {
            String username = authentication.getName();
            log.debug("获取当前用户 - 用户名: {}", username);

            User user = userMapper.findByAccount(username);
            if (user == null) {
                throw new RuntimeException("用户不存在: " + username);
            }

            log.debug("用户信息获取成功 - 用户ID: {}, 角色: {}", user.getId(), user.getUserType());
            return user.getId();
        }
        throw new RuntimeException("用户未认证");
    }

    private String getFilePathById(String fileId) {
        return Paths.get(uploadDir, fileId).toString();
    }

    private String getFileExtension(String filename) {
        if (filename == null) return "";
        int lastDotIndex = filename.lastIndexOf(".");
        return lastDotIndex > 0 ? filename.substring(lastDotIndex + 1).toLowerCase() : "";
    }

    // 请求和响应类
    @lombok.Data
    public static class InfoExtractionRequest {
        private String fileId;
        private String fileName; // 原始文件名
        private ExtractOptions extractOptions;
    }

    @lombok.Data
    public static class SingleExtractionRequest {
        private String fileId;
        private String fileName; // 原始文件名
        private String itemType; // basicInfo, keywords, abstract, references
    }

    @lombok.Data
    public static class ExtractOptions {
        private boolean extractBasicInfo = true;
        private boolean extractKeywords = true;
        private boolean extractAbstract = true;
        private boolean extractReferences = true;
        private String language = "zh";
    }

    @lombok.Data
    public static class FileUploadResponse {
        private String fileId;
        private String fileName;
        private String filePath;
        private Long fileSize;
    }
}